---
title: TypeScript
description: Astro에 내장된 TypeScript 지원을 사용하는 방법을 알아보세요.
i18nReady: true
---
import Since from '~/components/Since.astro';
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro';

Astro는 [TypeScript](https://www.typescriptlang.org/)를 기본적으로 지원합니다. Astro 프로젝트에서 `.ts` 및 `.tsx` 파일을 가져오고, [Astro 컴포넌트](/ko/basics/astro-components/#컴포넌트-스크립트)에 직접 TypeScript 코드를 작성할 수 있으며, 원하는 경우 Astro 구성에 [`astro.config.ts`](/ko/guides/configuring-astro/#astro-구성-파일) 파일을 사용할 수도 있습니다.

TypeScript를 사용하면 코드에서 객체 및 컴포넌트의 형태를 정의하여 런타임 시 오류를 방지할 수 있습니다. 예를 들어 TypeScript를 사용하여 [컴포넌트의 props에 타입을 지정](#컴포넌트-props)하면 컴포넌트가 허용하지 않는 prop을 설정할 경우 편집기에서 오류가 발생합니다.

Astro 프로젝트에서 TypeScript 코드를 작성하지 않아도 이점을 누릴 수 있습니다. Astro는 항상 컴포넌트 코드를 TypeScript로 처리하며, [Astro VS Code 확장 프로그램](/ko/editor-setup/)은 자동 완성, 힌트 및 편집기 오류를 제공하기 위해 최대한 많은 정보를 추론합니다.

Astro 개발 서버는 타입 검사를 수행하지 않지만, [별도의 스크립트](#타입-검사)를 사용하여 명령줄에서 타입 오류를 검사할 수 있습니다.

## 설정

Astro 시작 프로젝트에는 `tsconfig.json` 파일이 포함되어 있습니다. TypeScript 코드를 작성하지 않더라도 Astro 및 VS Code와 같은 도구가 프로젝트를 이해하는 방법을 알 수 있도록 하므로 이 파일은 중요합니다. `tsconfig.json` 파일이 없으면 일부 기능 (예: npm 패키지 가져오기)이 편집기에서 완전히 지원되지 않습니다. Astro를 수동으로 설치하는 경우 이 파일을 직접 만들어야 합니다.

### TSConfig 템플릿

Astro에는 확장 가능한 세 가지 `tsconfig.json` 템플릿인 `base`, `strict` 및 `strictest`가 포함되어 있습니다. `base` 템플릿은 최신 JavaScript 기능에 대한 지원을 활성화하며 다른 템플릿의 기반으로도 사용됩니다. 프로젝트에서 TypeScript를 작성하려는 경우 `strict` 또는 `strictest`를 사용하는 것이 좋습니다. [astro/tsconfigs/](https://github.com/withastro/astro/blob/main/packages/astro/tsconfigs/)에서 세 가지 템플릿 구성을 보고 비교할 수 있습니다.

템플릿 중 하나를 상속하려면 [`extends` 설정](https://www.typescriptlang.org/tsconfig#extends)을 사용하세요.

```json title="tsconfig.json"
{
  "extends": "astro/tsconfigs/base"
}
```

또한 Astro 타입을 활용하고 빌드된 파일의 검사를 피하기 위해 다음과 같이 `include` 및 `exclude`를 설정하는 것이 좋습니다.

```json title="tsconfig.json" ins={3-4}
{
  "extends": "astro/tsconfigs/base",
  "include": [".astro/types.d.ts", "**/*"],
  "exclude": ["dist"]
}
```

### TypeScript 편집기 플러그인

[공식 Astro VS Code 확장 프로그램](https://marketplace.visualstudio.com/items?itemName=astro-build.astro-vscode)을 사용하지 않을 때 [Astro TypeScript 플러그인](https://www.npmjs.com/package/@astrojs/ts-plugin)을 별도로 설치할 수 있습니다. 이 플러그인은 VSCode 확장 프로그램에 의해 자동으로 설치 및 구성되므로 둘 다 설치할 필요는 없습니다.

이 플러그인은 편집기에서만 실행됩니다. 터미널에서 `tsc`를 실행하면 `.astro` 파일은 완전히 무시됩니다. 대신 [`astro check` CLI 명령](/ko/reference/cli-reference/#astro-check)을 사용하여 `.astro` 및 `.ts` 파일을 모두 검사할 수 있습니다.

이 플러그인은 `.ts` 파일에서 `.astro` 파일을 가져오는 것도 지원합니다 (다시 내보내기에 유용할 수 있음).

<PackageManagerTabs>
  <Fragment slot="npm">
  ```shell
  npm install @astrojs/ts-plugin
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```shell
  pnpm add @astrojs/ts-plugin
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```shell
  yarn add @astrojs/ts-plugin
  ```
  </Fragment>
</PackageManagerTabs>

그런 다음 `tsconfig.json`에 다음을 추가하세요.

```json title="tsconfig.json"
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "@astrojs/ts-plugin"
      },
    ],
  }
}
```
플러그인이 작동하는지 확인하려면 `.ts` 파일을 만들고 Astro 컴포넌트를 가져옵니다. 편집기에서 경고 메시지가 표시되지 않아야 합니다.

### UI 프레임워크

프로젝트에서 [UI 프레임워크](/ko/guides/framework-components/)를 사용하는 경우 프레임워크에 따라 추가 설정이 필요할 수 있습니다. 자세한 내용은 프레임워크의 TypeScript 문서를 참조하세요. ([Vue](https://ko.vuejs.org/guide/typescript/overview.html#using-vue-with-typescript), [React](https://react-typescript-cheatsheet.netlify.app/docs/basic/setup), [Preact](https://preactjs.com/guide/v10/typescript/), [Solid](https://www.solidjs.com/guides/typescript), [Svelte](https://svelte.dev/docs/svelte/typescript))

## 타입 가져오기

가능하면 명시적 타입 가져오기 및 내보내기를 사용하세요.

```js del={1} ins={2} ins="type"
import { SomeType } from "./script";
import type { SomeType } from "./script";
```

이렇게 하면 Astro의 번들러가 가져온 타입을 JavaScript인 것처럼 잘못 번들링하려고 시도하는 엣지 케이스를 방지할 수 있습니다.

`tsconfig.json` 파일에서 타입 가져오기를 적용하도록 TypeScript를 구성할 수 있습니다. [`verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig#verbatimModuleSyntax)를 `true`로 설정하세요. TypeScript는 가져오기를 확인하고 `import type`을 사용해야 하는 시점을 알려줍니다. 이 설정은 모든 프리셋에서 기본적으로 활성화되어 있습니다.

```json title="tsconfig.json" ins={3}
{
  "compilerOptions": {
    "verbatimModuleSyntax": true
  }
}
```

## 별칭 가져오기

Astro는 `tsconfig.json` `paths` 구성에서 정의하는 별칭 가져오기를 지원합니다. 자세한 내용은 [가져오기 가이드](/ko/guides/imports/#별칭)를 참조하세요.

```astro title="src/pages/about/nate.astro" "@components" "@layouts"
---
import HelloWorld from "@components/HelloWorld.astro";
import Layout from "@layouts/Layout.astro";
---
```

```json title="tsconfig.json" {4-5}
{
  "compilerOptions": {
    "paths": {
      "@components/*": ["./src/components/*"],
      "@layouts/*": ["./src/layouts/*"]
    }
  }
}
```

## 전역 타입 확장하기

`src/env.d.ts`를 생성하여 사용자 정의 타입 선언을 추가하거나, `tsconfig.json` 없이 Astro의 타입을 활용할 수 있습니다.

```ts title="src/env.d.ts"
// 사용자 정의 타입을 선언합니다.
declare var myString: string;

// Astro의 타입입니다. `tsconfig.json`이 이미 있는 경우에는 필요하지 않습니다.
/// <reference path="../.astro/types.d.ts" />
```

### `window` 및 `globalThis` 확장

전역 객체에 속성을 추가하려는 경우가 있을 수 있습니다. `env.d.ts` 파일에 `declare` 키워드를 사용하여 최상위 선언을 추가하면 됩니다.

```ts title="src/env.d.ts"
declare var myString: string;
declare function myFunction(): boolean;
```

이렇게 하면 `window.myString` 및 `window.myFunction`뿐만 아니라 `globalThis.myString` 및 `globalThis.myFunction`에 타입이 제공됩니다.

`window`는 클라이언트 측 코드에서만 사용할 수 있습니다. `globalThis`는 서버 측과 클라이언트 측 모두에서 사용할 수 있지만, 서버 측 값은 클라이언트와 공유되지 않습니다.

`window` 객체의 속성에만 타입을 추가하려면 `Window` 인터페이스를 사용하세요.

```ts title="src/env.d.ts"
interface Window {
	myFunction(): boolean;
}
```

### 비표준 속성 추가하기

사용자 정의 속성이나 CSS 속성에 대한 타입을 정의하고 싶을 수도 있습니다. `.d.ts` 파일에서 `astroHTML.JSX` 네임스페이스를 재선언하여 기본 JSX 정의를 확장하면 비표준 속성을 추가할 수 있습니다.

```ts title="src/env.d.ts"
declare namespace astroHTML.JSX {
  interface HTMLAttributes {
    "data-count"?: number;
    "data-label"?: string;
  }

  // 스타일 객체에 사용자 정의 CSS 속성을 추가합니다.
  interface CSSProperties {
    "--theme-color"?: "black" | "white";
  }
}
```

:::note
`astroHTML`은 `.astro` 컴포넌트에 전역적으로 주입됩니다. TypeScript 파일에서 사용하려면 [삼중 슬래시 지시어](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html)를 사용하세요.

```ts
/// <reference types="astro/astro-jsx" />

type MyAttributes = astroHTML.JSX.ImgHTMLAttributes;
```
:::

### 가져오기 사용하기

[동적 가져오기](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import)를 사용하면 프로젝트 또는 외부 라이브러리에서 선언된 타입을 재사용하여 전역 타입을 확장할 수 있습니다.

```ts title="src/env.d.ts"
type Product = {
  id: string;
  name: string;
  price: number;
};

declare namespace App {
  interface Locals {
    orders: Map<string, Product[]>
    session: import("./lib/server/session").Session | null;
    user: import("my-external-library").User;
  }
}
```

`.d.ts`는 [앰비언트 모듈](https://www.typescriptlang.org/docs/handbook/modules/reference.html#ambient-modules) 선언 파일입니다. 구문은 ES 모듈과 유사하지만, 최상위 수준에서 가져오기/내보내기를 허용하지 않습니다. Typescript가 이를 감지하면 해당 파일을 [모듈 확장 파일](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation)로 간주하여 전역 타입 정의가 깨질 수 있습니다.

## 컴포넌트 Props

Astro는 TypeScript를 통해 컴포넌트 props의 타입을 지원합니다. 활성화하려면 컴포넌트 프런트매터에 TypeScript `Props` 인터페이스를 추가하세요. `export` 구문을 사용할 수 있지만 필수는 아닙니다. [Astro VSCode 확장 프로그램](/ko/editor-setup/)은 `Props` 인터페이스를 자동으로 찾아서 다른 템플릿에서 해당 컴포넌트를 사용할 때 적절한 TS 지원을 제공합니다.

```astro title="src/components/HelloProps.astro" ins={2-5}
---
interface Props {
  name: string;
  greeting?: string;
}
const { greeting = "Hello", name } = Astro.props;
---
<h2>{greeting}, {name}!</h2>
```

### 일반적인 prop 타입 패턴

- 컴포넌트가 props 또는 슬롯 콘텐츠를 사용하지 않는 경우 `type Props = Record<string, never>`를 사용할 수 있습니다.
- 컴포넌트의 기본 슬롯에 자식을 전달해야 하는 경우 `type Props = { children: any; };`를 사용하여 이를 적용할 수 있습니다.

## 타입 유틸리티

<p><Since v="1.6.0" /></p>

Astro는 일반적인 prop 타입 패턴을 위한 몇 가지 내장 유틸리티 타입을 제공합니다. 이러한 타입은 `astro/types` 진입점에서 사용할 수 있습니다.

### 내장 HTML 속성

Astro는 마크업이 유효한 HTML 속성을 사용하고 있는지 검사하기 위한 `HTMLAttributes` 타입을 제공합니다. 이러한 타입을 사용하여 컴포넌트 props를 빌드할 수 있습니다.

예를 들어 `<Link>` 컴포넌트를 빌드하는 경우 컴포넌트의 prop 타입에서 `<a>` 태그에 대한 기본 HTML 속성을 미러링하기 위해 다음을 수행할 수 있습니다.

```astro title="src/components/Link.astro" ins="HTMLAttributes" ins="HTMLAttributes<'a'>"
---
import type { HTMLAttributes } from "astro/types";

// `type`을 사용합니다.
type Props = HTMLAttributes<"a">;

// 또는 `interface`를 사용하여 확장합니다.
interface Props extends HTMLAttributes<"a"> {
  myProp?: boolean;
}

const { href, ...attrs } = Astro.props;
---
<a href={href} {...attrs}>
  <slot />
</a>
```

### `ComponentProps` 타입

<p><Since v="4.3.0" /></p>

이 타입 내보내기를 사용하면 다른 컴포넌트가 `Props` 타입을 직접 내보내지 않더라도 해당 컴포넌트에서 허용하는 `Props`를 참조할 수 있습니다.

다음 예제는 `<Button />` 컴포넌트의 `Props` 타입을 참조하기 위해 `astro/types`의 `ComponentProps` 유틸리티를 사용하는 방법을 보여줍니다.

```astro title="src/pages/index.astro"
---
import type { ComponentProps } from "astro/types";
import Button from "./Button.astro";

type ButtonProps = ComponentProps<typeof Button>;
---
```

### 다형적 타입

<p><Since v="2.5.0" /></p>

Astro에는 다양한 HTML 요소로 렌더링할 수 있는 컴포넌트를 완전한 타입 안전성을 갖춰 더 쉽게 빌드할 수 있도록 도와주는 도우미가 포함되어 있습니다. 이는 전달된 props에 따라 `<a>` 또는 `<button>`으로 렌더링할 수 있는 `<Link>`와 같은 컴포넌트에 유용합니다.

아래 예제는 모든 HTML 요소로 렌더링할 수 있는 완전한 타입의 다형적 컴포넌트를 구현합니다. `as` prop이 유효한 HTML 요소인지 확인하기 위해 [`HTMLTag`](#내장-html-속성) 타입이 사용됩니다.

```astro
---
import type { HTMLTag, Polymorphic } from "astro/types";

type Props<Tag extends HTMLTag> = Polymorphic<{ as: Tag }>;

const { as: Tag, ...props } = Astro.props;
---
<Tag {...props} />
```

### `getStaticPaths()` 타입 추론

<p><Since v="2.1.0" /></p>

Astro는 동적 라우트를 위한 [`getStaticPaths()`](/ko/reference/routing-reference/#getstaticpaths) 함수에서 반환된 타입을 처리하는 도우미를 포함합니다.

`InferGetStaticParamsType`으로 [`Astro.params`](/ko/reference/api-reference/#params)의 타입을 얻고, `InferGetStaticPropsType`으로 [`Astro.props`](/ko/reference/api-reference/#props)의 타입을 얻을 수 있습니다. 또는 `GetStaticPaths`를 사용하여 두 타입을 모두 얻을 수 있습니다.

```astro title="src/pages/posts/[...id].astro" {2-6,18-19} "satisfies GetStaticPaths;"
---
import type {
  InferGetStaticParamsType,
  InferGetStaticPropsType,
  GetStaticPaths,
} from "astro";

export const getStaticPaths = (async () => {
  const posts = await getCollection("blog");
  return posts.map((post) => {
    return {
      params: { id: post.id },
      props: { draft: post.data.draft, title: post.data.title },
    };
  });
}) satisfies GetStaticPaths;

type Params = InferGetStaticParamsType<typeof getStaticPaths>;
type Props = InferGetStaticPropsType<typeof getStaticPaths>;

const { id } = Astro.params as Params;
//                   ^? { id: string; }

const { title } = Astro.props;
//                      ^? { draft: boolean; title: string; }
---
```

## 타입 검사

편집기에서 타입 오류를 확인하려면 [Astro VS Code 확장 프로그램](/ko/editor-setup/)이 설치되어 있는지 확인하세요. `astro start` 및 `astro build` 명령은 esbuild로 코드를 트랜스파일하지만 타입 검사를 실행하지는 않습니다. 코드에 TypeScript 오류가 포함된 경우 빌드되지 않도록 하려면 `package.json`의 "build" 스크립트를 다음과 같이 변경하세요.

```json title="package.json" del={3} ins={4} ins="astro check &&"
{
  "scripts": {
    "build": "astro build",
    "build": "astro check && astro build",
  },
}
```

:::note
`astro check`는 TypeScript 프로젝트에 포함된 모든 파일을 검사합니다. Svelte 및 Vue 파일의 타입을 검사하려면 각각 [`svelte-check`](https://www.npmjs.com/package/svelte-check) 및 [`vue-tsc`](https://www.npmjs.com/package/vue-tsc) 패키지를 사용할 수 있습니다.
:::

import ReadMore from '~/components/ReadMore.astro'

<ReadMore>Astro에서 [`.ts` 파일 가져오기](/ko/guides/imports/#typescript)에 대해 자세히 알아보세요.</ReadMore>

<ReadMore>[TypeScript 구성](https://www.typescriptlang.org/tsconfig/)에 대해 자세히 알아보세요.</ReadMore>

## 문제 해결

### 동시에 여러 JSX 프레임워크의 타입 지정 시 오류 발생

동일한 프로젝트에서 여러 JSX 프레임워크를 사용하는 경우 문제가 발생할 수 있습니다. 각 프레임워크는 `tsconfig.json`에 서로 다른 설정, 때로는 충돌하는 설정이 필요하기 때문입니다. 

**해결**: 사용하는 프레임워크에 맞게 [`jsxImportSource` 설정](https://www.typescriptlang.org/tsconfig#jsxImportSource)을 `react`(기본값), `preact` 또는 `solid-js`로 설정합니다. 그리고 충돌하는 각각의 파일에 [pragma 주석](https://www.typescriptlang.org/docs/handbook/jsx.html#configuring-jsx)을 사용하세요.

**해결 방법**: 가장 많이 사용하는 프레임워크에 따라 [`jsxImportSource`](https://www.typescriptlang.org/tsconfig#jsxImportSource)를 `react` (기본값), `preact` 또는 `solid-js`로 설정합니다. 그런 다음 다른 프레임워크의 충돌하는 파일에서 [pragma 주석](https://www.typescriptlang.org/docs/handbook/jsx.html#configuring-jsx)을 사용합니다.

`jsxImportSource: react` (기본 설정)의 경우 다음을 사용합니다.

```jsx
// Preact
/** @jsxImportSource preact */

// Solid
/** @jsxImportSource solid-js */
```
